<template>
  <Dialog
    :title="`权限配置--${permissionData.entityDisplayName}`"
    @handle-confirm="handleConfirm"
    @open="handleDialogOpen"
  >
    <div
      class="permissionsFormInner"
      v-loading="formLoading"
    >
      <el-tabs tab-position="left">
        <el-tab-pane
          v-for="(item,index) in permissionData.groups"
          :key="item.name"
          :label="item.displayName"
        >
          <el-tree
            :ref="(el:any) => permissionTreeRefs[index] = el"
            check-strictly
            :data="item.data"
            :props="treeDefaultProps"
            show-checkbox
            default-expand-all
            node-key="name"
            class="permission-tree"
          />
        </el-tab-pane>
      </el-tabs>
    </div>
  </Dialog>
</template>

<script setup lang="ts">
import Dialog from '@/components/Dialog/index.vue'
import { getPermissions, updatePermissions } from '@/http/permissions'
import { getRole } from '@/http/role'
import { IGetPermission, IGetPermissionRes, IPermission } from '@/http/types/permissions'
import { IRole } from '@/http/types/role'
import { IUser } from '@/http/types/user'
import { getUser } from '@/http/user'
import { ElNotification } from 'element-plus'
// import { IElTree } from '@/types/element-plus'
import { nextTick, onBeforeUpdate, reactive, ref } from 'vue'

const props = defineProps({
  providerName: {
    type: String,
    default: 'R'
  },
  editId: {
    type: String,
    default: ''
  }
})
interface EmitsType {
  (e: 'success'): void
}
const emit = defineEmits<EmitsType>()
// 树组件 ref 列表
const permissionTreeRefs = ref<any>([])
onBeforeUpdate(() => {
  permissionTreeRefs.value = []
})
// onUpdated(() => {
//   console.log(permissionTreeRefs.value)
// })
const treeDefaultProps = {
  children: 'children',
  label: 'label'
}
const permissionData = reactive<IGetPermissionRes>({
  entityDisplayName: '',
  groups: []
})
const handleConfirm = async () => {
  const tempData:{
    isGranted: boolean
    name: string
  }[] = []
  for (const i in permissionData.groups) {
    const keys = permissionTreeRefs.value[i].getCheckedKeys()
    const group = permissionData.groups[i]
    for (const j in group.permissions) {
      if (
        group.permissions[j].isGranted &&
            !keys.some((v:string) => v === group.permissions[j].name)
      ) {
        tempData.push({
          isGranted: false,
          name: group.permissions[j].name
        })
      } else if (
        !group.permissions[j].isGranted &&
            keys.some((v:string) => v === group.permissions[j].name)
      ) {
        tempData.push({ isGranted: true, name: group.permissions[j].name })
      }
    }
  }
  await updatePermissions(
    { providerKey: providerKey.value, providerName: props.providerName },
    { permissions: tempData }
  )
  ElNotification({
    title: '保存成功',
    message: '用户权限设置成功',
    type: 'success',
    duration: 2000
  })
  emit('success')
}
const providerKey = ref('')
const handleGetPermissions = async (row:IUser|IRole) => {
  props.providerName === 'R'
    ? (providerKey.value = row.name)
    : (providerKey.value = row.id || '')
  const res = await getPermissions({
    providerName: props.providerName,
    providerKey: providerKey.value
  })
  permissionData.entityDisplayName = res.entityDisplayName
  permissionData.groups = res.groups
  permissionData.groups.forEach(item => {
    item.data = transformPermissionTree(item.permissions)
  })
  const defaultKeys:Array<string[]> = []
  for (const i in permissionData.groups) {
    const group = permissionData.groups[i]
    const keys:string[] = group.permissions.filter(e => e.isGranted).map(e => e.name)
    defaultKeys.push(keys)
  }
  await nextTick()
  defaultKeys.forEach((keys, i) => {
    permissionTreeRefs.value[i].setCheckedKeys(keys)
  })
}
interface ITreeItem{
  name:string,
  label:string,
  disabled:boolean,
  children: ITreeItem[]
}
const transformPermissionTree = (permissions:IPermission[], name:string|null = null) => {
  const arr:ITreeItem[] = []
  if (!permissions || !permissions.some(v => v.parentName === name)) {
    return arr
  }

  const parents = permissions.filter(v => v.parentName === name)
  for (const i in parents) {
    let label = ''
    if (props.providerName === 'R') {
      label = parents[i].displayName || ''
    } else if (props.providerName === 'U') {
      label =
            parents[i].displayName +
            ' ' +
            (parents[i].grantedProviders || []).map(provider => {
              return `${provider.providerName}: ${provider.providerKey}`
            })
    }
    arr.push({
      name: parents[i].name,
      label,
      disabled: isGrantedByOtherProviderName(
        parents[i].grantedProviders || []
      ),
      children: transformPermissionTree(permissions, parents[i].name)
    })
  }
  return arr
}
const isGrantedByOtherProviderName = (grantedProviders:IGetPermission[]) => {
  if (grantedProviders.length) {
    return (
      grantedProviders.findIndex(p => p.providerName !== props.providerName) >
          -1
    )
  }
  return false
}
const formLoading = ref(false)
const handleDialogOpen = async () => {
  formLoading.value = true
  let data:IUser|IRole|null = null
  if (props.providerName === 'R') {
    data = await getRole(props.editId)
  } else if (props.providerName === 'U') {
    data = await getUser(props.editId)
  }
  if (data) {
    await handleGetPermissions(data).finally(() => {
      formLoading.value = false
    })
  }
}
// const loadRole = async () => {
//   const roleInfo = await getRole(props.editId)
// }
// const loadUser = async () => {
//   const userInfo = await getUser(props.editId)
// }
</script>

<style scoped lang="scss">

</style>
